//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<IGuiComp.h>
///	@path	~/src/gui/
///	@date	2008/05/19
///	@desc	.

#pragma once

#include "xeres.h"

#include "lib/math/pair.h"
#include "lib/math/vector.h"
#include "lib/math/rect.h"

#include "object/IObject.h"

#include "gui/input/input.h"
#include "gui/updater.h"

namespace xeres {

	// forward declaration
	class IGuiForm;
	class IStyle;
	class Composition;

	/*! 
		\class	IGuiComp
		\brief	Base interface of XGUI component.
	*/
	class IGuiComp : public IObject
	{
	public:

		/// \ctor
		IGuiComp( void );

		/// \dtor
		virtual ~IGuiComp( void );

		DECL_IOBJECT_INTERFACE( IGuiComp , IObject );

	public:

		/// \name XGui Component Attributes
		//@{

		/// \brief	Get position of component (in relative coordinate).
		virtual Pair<int> GetPosition( void ) = 0;

		/// \brief	Set position of component.
		virtual bool SetPosition( const Pair<int>& pos ) = 0;

		/// \brief	Get screen position.
		virtual Pair<int> GetScreenPosition( void ) = 0;

		/// \brief	Get size of component.
		virtual Pair<int> GetSize( void ) = 0;

		/// \brief	Set size of component.
		virtual bool SetSize( const Pair<int>& size ) = 0;

		/// \brief	Set placement.
		virtual bool SetPlacement( const Rect<int>& placement ) = 0;

		/// \brief	Get placement rect.
		virtual Rect<int> GetPlacement( void ) = 0;

		/// \brief	Get parent component.
		virtual RefWeak<IGuiForm> GetParent( void ) = 0;

		/// \brief	Set parent component.
		virtual bool SetParent( RefWeak<IGuiForm> parent ) = 0;

		/// \brief	Get component visibility.
		virtual bool GetVisible( void ) = 0;

		/// \brief	Set component visibility.
		virtual bool SetVisible( bool visible ) = 0;

		/// \brief	Get component enable (to input).
		virtual bool GetEnable( void ) = 0;

		/// \brief	Set component enable.
		virtual bool SetEnable( bool enable ) = 0;

		/// \brief	Get focus state.
		virtual bool GetFocus( void ) = 0;

		/// \brief	Set focus state.
		virtual bool SetFocus( bool focus ) = 0;

		/// \brief	Close component.
		virtual void Close( void ) = 0;

		/// \brief	Hit test.
		virtual bool HitTest( const Pair<int>& pt ) { return GetPlacement().is_inside(pt); };

		/// \brief	Determine if it's edit control (desired special process).
		virtual bool IsEditControl( void ) const { return false; }

		/// \brief	Can have focus.
		virtual bool CanHaveFocus( void ) const { return true; }

		/// \brief	Can dragged.
		virtual bool CanDragged( void ) const { return false; }

		/// \brief	Can drop.
		virtual bool CanDrop( void ) const { return false; }

		/// \brief	Get component ID.
		uint32 GetId( void ) const { return m_id; }

		//@}

		/// \name Message Passing
		//@{

		///	\brief	Process key input message.
		virtual HandleInput OnKeyInput( Updater& updater ) = 0;

		///	\brief	Process mouse input message.
		virtual HandleInput OnMouseInput( Updater& updater ) = 0;

		/// \brief	Auto dispatch message.
		HandleInput OnInput( Updater& updater );

		/// \brief	Call when mouse enter component.
		virtual void OnMouseEnter( Updater& updater , RefWeak<IGuiComp> last ) = 0;

		/// \brief	Call when mouse leave component.
		virtual void OnMouseLeave( Updater& updater , RefWeak<IGuiComp> next ) = 0;

		/// \brief	Call when mouse hover component.
		virtual void OnMouseHover( Updater& updater ) = 0;

		/// \brief	Call when focus in.
		virtual void OnFocusIn( Updater& updater , RefWeak<IGuiComp> last ) = 0;

		/// \brief	Call when focus out.
		virtual void OnFocusOut( Updater& updater , RefWeak<IGuiComp> next ) = 0;

		/// \brief	Call when close window.
		virtual void OnClose( void ) = 0;

		//@}

		/// \name Presentation Manipulation
		//@{

		/// \brief	Tick update.
		virtual void Tick( Updater& updater , float dTime ) = 0;

		/// \brief	Draw XGUI component to composition.
		virtual void Draw( Composition& composition ) = 0;

		//@}

		/// \brief	Bring component to front.
		void BringToFront( void ) { ActiveComponent(); }

		/// \brief	Get component active id.
		uint32 GetActiveId( void ) const { return m_activeId; }

	protected:

		/// \brief	Active component, update active id.
		void ActiveComponent( void );

	private:

		//@ data

		// component unique id.
		uint32				m_id;

		// active id, used to sort components.
		uint32				m_activeId;
	};

} // namespace xeres
